#!/usr/bin/env python2
import colorama, tempfile, os, time, re, sys, HumanReadableRoundNames, Combinations, Matches, TickBasedRandom
from Team import Team

fileName = ""
teamsList = [ ]
origTeams = []
roundName = ""
LastFixtures = ""

def GetTempPath():
    with tempfile.NamedTemporaryFile() as tempFile:
        path = os.path.dirname(tempFile.name)
    return "/var/tmp" if (path.startswith("/tmp") or path == "/tmp/") and os.path.exists("/var/tmp") else path

def GetNewFileName():
    tempPath = GetTempPath()
    return os.path.join(tempPath, "MISTBowl_Brackets_{0:.0f}.tmp".format(time.time()*1000))

def GetExistingFileName():
    try:
        return sorted([a for a in os.listdir(GetTempPath()) if re.match(r'MISTBowl_Brackets_[0-9]+[.]tmp$', a)]).pop()
    except IndexError:
        raise IOError("no existing tournament file found")

def Clear():
    sys.stdout.write("\x1Bc\x1B[97;44m\x1B[3J\x1B[H\x1B[2J")
    print("MIST Bowl Bracket Software")
    print("Copyright (c) 2018 Muhammad Mu'a" + unichr(240).encode('utf-8') + " Imtiaz")
    maxLength = 40
    if len(teamsList) > 0:
        pads = [ max([len(a.teamId) for a in teamsList]), max([len(a.region) for a in teamsList]), max([len(str(a.points)) for a in teamsList]) ]
        displayPoints = any([a.points != 0 for a in teamsList])
        teamsTable = [ [a.teamId.ljust(pads[0], " "), a.region.ljust(pads[1], " "),  str(a.points).rjust(pads[2], " ") if displayPoints else "" ] for a in sorted(teamsList, key=lambda b: b.points,reverse=True) ]
        maxLength = max(len(HumanReadableRoundNames.GetHumanReadableName(roundName)) if roundName != "" else 0, max(40, max([len("".join(a)) for a in teamsTable])))
        for i in range(maxLength):
            sys.stdout.write("-")
        print(os.linesep + os.linesep.join(["\t".join(a) for a in teamsTable]))
        if roundName != "":
            print(HumanReadableRoundNames.GetHumanReadableName(roundName))
    for i in range(maxLength):
        sys.stdout.write("-")
    print("")

def WriteToFile():
    with open(fileName, "w") as handle:
        for team in teamsList:
            handle.write("TEAM:" + team.teamId + "," + team.region + "\n")
            if roundName != "":
                handle.write(roundName + ":" + ",".join([a.teamId for a in teamsList]) + "\n")
            global LastFixtures
            if LastFixtures != "":
                handle.write(LastFixtures + "\n")
                LastFixtures = ""

def ReadFromFile():
    raise NotImplementedError()

sys.stdout.write("\x1B]0;MIST Bowl Bracket Software\x07")
Clear()
while True:
    print("Type 'c' to create a new tournament file, 'e' to use an existing one, or 'q' to quit, then press [Enter].")
    option = raw_input()
    if option == 'c':
        print("OK, creating new file. . .")
        fileName = GetNewFileName()
        while os.path.exists(fileName):
            fileName = GetNewFileName()
        break
    if option == 'e':
        print("OK, using existing file. . .")
        fileName = GetExistingFileName()
        break
    if option == 'q':
        exit(0)
    print("Invalid option '" + option + "'.");
Clear()
if not os.path.exists(fileName):
    print("For each team participating in the MIST Bowl tournament, please type the team ID, followed by a comma, followed by the team's region name, like as follows:")
    sys.stdout.write("\x1B[92m")
    print("1000,Detroit")
    print("1100/1600,Toronto")
    sys.stdout.write("\x1B[1;95m")
    print("MAKE SURE ALL REGION NAMES ARE SPELLED CORRECTLY!")
    sys.stdout.write("\x1B[22;97m")
    print("Press [Enter] twice when finished.")
    print("")
    while True:
        s = raw_input().upper()
        if s == "" :
            break
        if re.match(r'[0-9]+(/[0-9]+)* *, *[^ ,][^,]*$', s) == None or any([any([a in b.teamId.split("/") for b in teamsList]) for a in s.split(",")[0].split("/")]):
            raise ValueError("team ID cannot be repeated")
        teamsList.append(Team(re.sub(r' *, * ', r',', s).split(',')))
    if len(teamsList) == 0:
        raise ValueError("list of teams is empty")
    origTeamsList = list(teamsList)
    Clear()
    WriteToFile()
    sys.stdout.write("Please enter the number of preliminary rounds in this tournament: ")
    sys.stdout.flush()
    prelimRounds = int(raw_input())
    while True:
        sys.stdout.write("Please enter the number of matches taking place in each preliminary round: ")
        sys.stdout.flush()
        try:
            matchCount = int(raw_input())
        except:
            pass
        if len(teamsList) % matchCount == 0:
            break
        sys.stdout.write("\x1B[91m")
        print("That is not a valid number of matches given the number of teams. Please try again.")
        sys.stdout.write("\x1B[97m")
        print("")
    for i in range(prelimRounds):
        roundName = "PRELIM" + str(i + 1) + "/" + str(prelimRounds)
        Clear()
        print("The following matches will take place in this round:")
        for match in Combinations.GenerateBestMatches(teamsList, len(teamsList) / matchCount, matchCount, origTeamsList):
            Matches.AddMatch(match)
            print(" v. ".join([a.teamId for a in match]))
        sys.stdout.write("\x1B[1;95m")
        print("MAKE SURE TO WRITE DOWN THIS MATCH LIST BEFORE CONTINUING.")
        sys.stdout.write("\x1B[22;97m")
        time.sleep(3)
        print("")
        print("Press [Enter] to continue. . .")
        raw_input()
        Clear()

        print("Please enter the number of points earned by each team.")
        for team in teamsList:
            sys.stdout.write(team.teamId + "," + team.region + ": ")
            sys.stdout.flush()
            team.points += int(raw_input())
    while roundName != "F":
        roundName = ""
        Clear()
        sys.stdout.write("Please enter the number of teams progressing to the next round: ")
        sys.stdout.flush()
        teamsList = [sorted(sorted(teamsList, key=lambda a: TickBasedRandom.GetInteger(0, sys.maxsize)), key=lambda a: a.points, reverse=True)[b] for b in range(int(raw_input()))]
        for team in teamsList:
            team.points = 0
        while True:
            sys.stdout.write("Please enter the number of matches taking place in this round: ")
            sys.stdout.flush()
            try:
                matchCount = int(raw_input())
            except:
                pass
            if len(teamsList) % matchCount == 0:
                break
            sys.stdout.write("\x1B[91m")
            print("That is not a valid number of matches given the number of teams. Please try again.")
            sys.stdout.write("\x1B[97m")
            print("")
        roundName = "F" if matchCount == 1 else "ROUNDOF" + str(matchCount)
        Clear()
        print("The following matches will take place in this round:")
        for match in Combinations.GenerateBestMatches(teamsList, len(teamsList) / matchCount, matchCount, origTeamsList):
            Matches.AddMatch(match)
            print(" v. ".join([a.teamId for a in match]))
        sys.stdout.write("\x1B[1;95m")
        print("MAKE SURE TO WRITE DOWN THIS MATCH LIST BEFORE CONTINUING.")
        sys.stdout.write("\x1B[22;97m")
        print("")
        time.sleep(3)
        print("Press [Enter] to continue. . .")
        raw_input()
        Clear()

        print("Please enter the number of points earned by each team.")
        for team in teamsList:
            sys.stdout.write(team.teamId + "," + team.region + ": ")
            sys.stdout.flush()
            team.points += int(raw_input())
    teamsList = sorted(sorted(teamsList, key=lambda a: TickBasedRandom.GetInteger(0, sys.maxsize)), key=lambda a: a.points, reverse=True)
    print("1ST PLACE CHAMPIONS: " + teamsList[0].teamId + "," + teamsList[0].region)
    print("2ND PLACE CHAMPIONS: " + teamsList[1].teamId + "," + teamsList[1].region)
    print("3RD PLACE CHAMPIONS: " + teamsList[2].teamId + "," + teamsList[2].region)
    print("Press [Enter] to quit. . .")
    raw_input()
    sys.stdout.write("\x1B0m")
    sys.stdout.flush()
